package org.jeecg.modules.cascv.image.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.apache.commons.lang3.StringUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.XPath;
import org.dom4j.io.SAXReader;
import org.jeecg.modules.cascv.image.entity.GdqvXml;
import org.jeecg.modules.cascv.image.mapper.GdqvXmlMapper;
import org.jeecg.modules.cascv.image.mapper.ShiYanCangSqlDaoMapper;
import org.jeecg.modules.cascv.image.service.IGdqvXmlService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.*;

/**
 * @Description: xml表
 * @Author: jeecg-boot
 * @Date:   2022-08-30
 * @Version: V1.0
 */
@Service
public class GdqvXmlServiceImpl extends ServiceImpl<GdqvXmlMapper, GdqvXml> implements IGdqvXmlService {

    @Autowired
    ShiYanCangSqlDaoMapper sqlDaoMapper;

    @Override
    @Transactional
    public void insert(MultipartFile file, Integer type, boolean flag) {
        String fileName = file.getOriginalFilename();
        SAXReader reader = new SAXReader();
        Document read = null;
        Long id = sqlDaoMapper.paraMaxId();
        if (null == id) {
            id = 1l;
        } else {
            id = id + 1;
        }
//        List<YinyongJiluEntity> yinyongJiluEntities = gmvYinyongJiluMapper.selectList(new QueryWrapper<YinyongJiluEntity>());
//        for (YinyongJiluEntity yinyongJiluEntity : yinyongJiluEntities) {
//            //1是指定引用 2选择引用 指定引用跨类型不更新（例如工程应用遥测）
//            if (yinyongJiluEntity.getYinyongType() == 2) {
//                //为了防止把原引用文件更新错误在后面加下横杠 2选择引用 批量更新
//                sqlDaoMapper.updateXuanzeZhixiangXmlDelFlag(yinyongJiluEntity.getXmlName() + "_");
//            }
//        }

        List<String> dbParaCodeList = new ArrayList<>();
        String tableName = StringUtils.substringBefore(fileName, ".");
        String bitString = "";// bit
        String Unit = "";//单位
        String paramNo = "";
        String DisplayFormat = "";
        String ParameterName = "";
        try {
            read = reader.read(file.getInputStream());

        } catch (DocumentException | IOException e) {
            e.printStackTrace();
        }

        GdqvXml gmvXml = baseMapper.selectOne(new QueryWrapper<GdqvXml>().eq("xml_name", tableName));
        if (gmvXml == null) {
            return;
        }
        if (gmvXml.getDelFlag().equals("1")) {
            return;
        }
        Integer xmlId = Integer.valueOf(String.valueOf(gmvXml.getId()));
        //sqlDaoMapper.selectXmlId(tableName);
        Map<String, String> map = new HashMap<>();
        map.put("t", "IDSParameter");
        int binaryCode = 0;
        XPath x = read.createXPath("/t:IDS_Parameter_root/t:Parameters/t:Parameter");
        x.setNamespaceURIs(map);
        List<Element> list = x.selectNodes(read);
        int sort = 1;


        //xml中的paraCode,后续通过读取xml把参数写入list
        List<String> xmlParaCodeList = new LinkedList<>();
        for (Element ele : list) {
            StringBuilder range = new StringBuilder();// 范围 现在上游传，不需要初始化

            Map<String, Object> addParaMap = new HashMap<>();
            paramNo = ele.elementText("ParameterNo");
            Unit = ele.elementText("Unit");
            DisplayFormat = ele.elementText("DisplayFormat");
            ParameterName = ele.elementText("ParameterName");
            String StopBit = "";
            String StartBit = "";
            String LowerLimit = "";
            String UpperLimit = "";
            String Value = "";
            String Description = "";
            String yuanlai = "";
            if (paramNo != null) {
                paramNo = !paramNo.equals("/") ? paramNo.replace("/", "_") : paramNo;
                paramNo = !paramNo.equals("-") ? paramNo.replace("-", "_") : paramNo;
                paramNo = !paramNo.equals("~") ? paramNo.replace("~", "_") : paramNo;
                paramNo = !paramNo.equals("(") ? paramNo.replace("(", "_") : paramNo;
                paramNo = !paramNo.equals(")") ? paramNo.replace(")", "_") : paramNo;
                paramNo = paramNo.replace(" ", "");
            }
            if (ParameterName == null) {
                ParameterName = "";
            }
            if (Unit == null) {
                Unit = "";
            }
            if (DisplayFormat == null) {
                DisplayFormat = "0";
            }
            List<Element> BitvaluesList = ele.elements("BitValues");
            List<Element> BitvalueList = ele.elements("ByteValue");
            List<Element> BitRangesList = ele.elements("BitRanges");
            List<Element> ByteRangeList = ele.elements("ByteRange");

            for (Element bitValue : BitRangesList) {
                StartBit = bitValue.elementText("StartBit");
                StopBit = bitValue.elementText("StopBit");
            }
            for (Element bitValue : BitvaluesList) {
                StartBit = bitValue.elementText("StartBit");
                StopBit = bitValue.elementText("StopBit");
                List<Element> BitValue = bitValue.elements("BitValue");
                for (Element value : BitValue) {
                    Value = value.elementText("Value");
                    Description = value.elementText("Description");
                    if (value == null) continue;
                    range.append(Value).append(" | ").append(Description).append("\\n ");
                }


                //  rangeString = Value+" | "+Description;

            }
            for (Element bitvalue : BitvalueList) {
                Value = bitvalue.elementText("Value");
                Description = bitvalue.elementText("Description");
                if (bitvalue == null) continue;
                range.append(Value).append(" | ").append(Description).append("\\n");
            }
//
            List<Element> BitRangeList = new ArrayList<>();
            for (Element bitRanges : BitRangesList) {
                StartBit = bitRanges.elementText("StartBit");
                StopBit = bitRanges.elementText("StopBit");
                BitRangeList = bitRanges.elements("BitRange");
                for (Element bitrange : BitRangeList) {
                    LowerLimit = bitrange.elementText("LowerLimit");
                    UpperLimit = bitrange.elementText("UpperLimit");
                    Description = bitrange.elementText("Description");
                    if (LowerLimit == null && UpperLimit == null) continue;
                    if (LowerLimit == null) {
                        LowerLimit = "";
                    }
                    if (UpperLimit == null) {
                        UpperLimit = "";
                    }
                    range.append(LowerLimit + "-" + UpperLimit).append(" | ").append(Description).append("\\n");
                }
            }
//
            for (Element bitRanges : ByteRangeList) {
                LowerLimit = bitRanges.elementText("LowerLimit");
                UpperLimit = bitRanges.elementText("UpperLimit");
                Description = bitRanges.elementText("Description");
                range.append(LowerLimit + "-" + UpperLimit).append(" | ").append(Description).append("\\n");
            }
            String rangeString = StringUtils.substringBeforeLast(range.toString(), "\\n");

            if (BitRangesList.size() != 0 || BitvaluesList.size() != 0) {
                if (StartBit.equals("")) {
                    bitString = StopBit;
                } else if (StopBit.equals("")) {
                    bitString = StartBit;
                } else if (StartBit.equals("") && StopBit.equals("")) {
                    bitString = "/";
                } else if (StartBit == null) {
                    bitString = "/";
                } else {
                    bitString = StopBit + "~" + StartBit;
                }
            }
            switch (DisplayFormat) {
                case "0":
                    binaryCode = 1;
                    break;
                case "浮点数":
                    binaryCode = 1;
                    break;
                case "十六进制":
                    binaryCode = 2;
                    break;
                case "时间码":
                    binaryCode = 3;
                    break;
                case "十进制整数":
                    binaryCode = 4;
                    break;
                case "二进制":
                    binaryCode = 5;
                    break;
                case "其它":
                    binaryCode = 6;
                    break;
            }

            //(PARA_ID, PARA_CODE, XML_ID, PARA_NAME, PARA_TYPE, PARA_NOTE, PARA_NAV_ID, CASSANDRA_TABLE, CASSANDRA_COLUM, BIT, UNIT,
            // CREATE_DATE, UPDATE_DATE, SORT, SOURCE, LIMIT, RANGE, DELETE_DATE, DEL_FLAG, CREATOR, UPDATER, PARA_FLAG, FUNC, ID_FUNC, BINARY_CODE)
            //
            //    (#{paraId}, #{paraCode}, #{xmlId}, #{ParameterName}, 'sys', NULL, NULL, #{cassandraTable}, #{cassandraColum}, #{BIT},
            //    #{unit}, NULL, NULL, NULL, NULL, #{LIMIT}, #{RANGE}, NULL, '0', NULL, NULL, 'sys', NULL, NULL, #{binaryCode})
            addParaMap.put("paraId", id);
            addParaMap.put("paraCode", paramNo);
            addParaMap.put("xmlId", xmlId);
            addParaMap.put("ParameterName", ParameterName);
            addParaMap.put("cassandraTable", tableName);
            addParaMap.put("cassandraColum", paramNo);
            addParaMap.put("BIT", bitString);
            addParaMap.put("unit", Unit);
            addParaMap.put("sort", sort);
            addParaMap.put("RANGE", rangeString.length() > 2000 ? "" : rangeString);//todo 以后确认
            addParaMap.put("binaryCode", binaryCode);
            if (flag) {
                addParaMap.put("con_specific_flag", type);
            }

            //把xml中的paraCode存入
            xmlParaCodeList.add(paramNo);
            //查看数据库里对应这个XML已经导入的参数
            dbParaCodeList = sqlDaoMapper.getParaCodeByXMlName(tableName);
            //如果包含，只更新
            if (dbParaCodeList.contains(paramNo)) {
                sqlDaoMapper.updateParam(ParameterName, Unit,  binaryCode, paramNo);
            } else {
                sqlDaoMapper.addParmSql(addParaMap);
                id++;
                sort++;
            }
            bitString = "";

            // if (isYinyiong == true) {
//                List<YinyongTempParaEntity> yinyongTempParaEntities = gmvYinyongTempParaMapper.selectList
//                        (new QueryWrapper<YinyongTempParaEntity>().eq("PARA_CODE", paramNo).eq("XML_ID", xmlId));
//                if (CollectionUtils.isNotEmpty(yinyongTempParaEntities)) {
//                    for (YinyongTempParaEntity yinyongTempParaEntity : yinyongTempParaEntities) {
//                        addParaMap.put("paraId", id);
//                        addParaMap.put("paraCode", yinyongTempParaEntity.getYinyongParaCode());
//                        addParaMap.put("xmlId", xmlId);
//                        addParaMap.put("ParameterName", yinyongTempParaEntity.getYinyongParaName());
//                        addParaMap.put("cassandraTable", "");
//                        addParaMap.put("cassandraColum", "");
//                        addParaMap.put("BIT", yinyongTempParaEntity.getYinyongBit());
//                        addParaMap.put("unit", yinyongTempParaEntity.getYinyongUnit());
//                        addParaMap.put("sort", sort);
//                        addParaMap.put("RANGE", yinyongTempParaEntity.getYinyongRange());
//                        addParaMap.put("binaryCode", yinyongTempParaEntity.getYinyongBinaryCode());
//                        if (flag) {
//                            addParaMap.put("con_specific_flag", type);
//                        }
//
//                        sqlDaoMapper.addParmSql(addParaMap);
//                        id++;
//                        sort++;
//                    }
//                }
            //}
        }

        //遍历数据库中存的参数，把xml中不存在数据库中存在的paraCode删除,目前先不启用
        for (String paraCode : dbParaCodeList) {
            if (!xmlParaCodeList.contains(paraCode)) {
                sqlDaoMapper.removeUnusedParam(paraCode);
            }
        }
    }
}
